package com.example.demo.service;

import com.example.demo.annotion.RequestLimit;
import com.example.demo.exception.RequestLimitException;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.net.HttpCookie;
import java.util.HashMap;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;


/**
 * 浙江卓锐科技股份有限公司 版权所有  Copyright 2018<br>
 *
 * @Description: <br>
 * @Project: eboos <br>
 * @CreateDate: Created in 2018/1/4 0004 下午 1:51 <br>
 * @Author: <a href="410508961@qq.com">夏凯</a>
 */
@Aspect
@Component
public class RequestLimitContract {
    private static final Logger logger = LoggerFactory.getLogger("RequestLimitLogger");
    private Map<String, Integer> redisTemplate = new HashMap<String, Integer>();

    //找到当前标签
    @Before("within(@org.springframework.stereotype.Controller *) && @annotation(limit)")
    /**
     * @ClassName: RequestLimitContract
     * @param joinPoint
     * @param limit
     * @Return: void
     * @Decription: 访问次数超限制的标签
     * @CreateDate: Created in 2018/1/4 0004 下午 1:56
     * @Author: <a href="410508961@qq.com">夏凯</a>
     * @Modify:
     */
    public void requestLimit(final JoinPoint joinPoint, RequestLimit limit) throws RequestLimitException {
        //Cookie cookie=new Cookie("cookie", "0");
       // cookie1.setMaxAge(10);   //存活期为10秒
        try {
            Object[] args = joinPoint.getArgs();
            HttpServletRequest request = null;
            for (int i = 0; i < args.length; i++) {
                if (args[i] instanceof HttpServletRequest) {
                    request = (HttpServletRequest) args[i];
                    break;
                }
            }
            if (request == null) {
                throw new RequestLimitException("方法中缺失HttpServletRequest参数");
            }
            String ip = request.getLocalAddr();
            String url = request.getRequestURL().toString();
            String key = "req_limit_".concat(url).concat(ip);
            if ( null==cookie.getValue()  || "".equals(cookie.getValue())) {
                cookie =new HttpCookie("cookie", "1");
            //if (redisTemplate.get(key) == null || redisTemplate.get(key)==0) {
                //redisTemplate.put(key, 1);
               // cookie=new HttpCookie("cookie", "1");
            } else {
               // redisTemplate.put(key, redisTemplate.get(key) + 1);
                cookie=new HttpCookie("cookie", String.valueOf(Integer.parseInt(cookie.getValue()+1)));
            }
            int count = Integer.parseInt(String.valueOf(Integer.parseInt(cookie.getValue())));
            if (count > 0) {
                Timer timer = new Timer();
                TimerTask task = new TimerTask() {    //创建一个新的计时器任务。
                    @Override
                    public void run() {
                        redisTemplate.remove(key);
                    }
                };
                timer.schedule(task, limit.time());
                //安排在指定延迟后执行指定的任务。task : 所要安排的任务。10000 : 执行任务前的延迟时间，单位是毫秒。
            }
            if (count >limit.count()) {
                logger.info("用户IP[" + ip + "]访问地址[" + url + "]超过了限定的次数[" + limit.count() + "]");
                throw new RequestLimitException();
            }
        } catch (RequestLimitException e) {
            throw e;
        } catch (Exception e) {
            logger.error("发生异常: ", e);
        }
    }
}
